#include "logfiledialog.h"
#include "ui_logfiledialog.h"

#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QProgressDialog>
#include <QDebug>

#define NUMBER_OF_LINES_TO_READ 1000

LogfileDialog::LogfileDialog(QWidget *parent,LineValidator* linevalidator, QString fileName) :
    QDialog(parent),
    m_ui(new Ui::LogfileDialog)
{
    this->m_lineValidator = linevalidator;
    this->m_file = NULL;
    this->m_invalidHighlighter = NULL;
    m_ui->setupUi(this);

    connect(this,SIGNAL(SIGshowSample()),this,SLOT(showSample()));
    connect(m_ui->rowsToShow,SIGNAL(valueChanged(int)),this,SLOT(showSample())); // do this here
    connect(this,SIGNAL(SIGshowTransformedSample()),this,SLOT(showTransformedSample()));

    connect(m_ui->durationSyntaxEdit,SIGNAL(textEdited(QString)),this,SLOT(updateDurationSyntax(QString)));
    connect(m_ui->statementSyntaxEdit,SIGNAL(textEdited(QString)),this,SLOT(updateStatementSyntax(QString)));
    connect(m_ui->lineSyntaxEdit,SIGNAL(textEdited(QString)),this,SLOT(updateLineSyntax(QString)));
    connect(m_ui->lineSyntaxEditInvalid,SIGNAL(textEdited(QString)),this,SLOT(updateInvalidLineSyntax(QString)));
    this->start(fileName);
}

void LogfileDialog::start(QString fileName)
{
    if (!fileName.isEmpty())
    {
        this->m_file = new QFile(fileName);
        m_totalsize = this->m_file->size();
        m_ui->filesizeLabel->setText(QString("File size: ")+QString::number(m_totalsize)+QString(" bytes"));
        // read a sample and display...
        if (! m_file->open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QMessageBox::critical(0,QString("No analysis started"), QString("You have to have an active analysis to be able to add a new logfile to the analysis."));
            exit(2);
        }
        else
        {
            //read the sample
            QTextStream in(&*m_file);
            QString line;
            int linesRead =0;
            QProgressDialog progressDialog("Reading sample. Please wait","Abort",0,NUMBER_OF_LINES_TO_READ,this);
            progressDialog.setWindowModality(Qt::WindowModal);
            while (!in.atEnd() && linesRead < NUMBER_OF_LINES_TO_READ)
            {
                line = in.readLine();
                linesRead++;
                m_sampleLines.append(line.trimmed());
                progressDialog.setValue(linesRead);
                if (progressDialog.wasCanceled())
                {
                    exit(3);
                    break;
                }
            }
            progressDialog.setValue(NUMBER_OF_LINES_TO_READ);
            emit SIGshowSample();           
            m_ui->rowsToShow->setMaximum(m_sampleLines.count());
            // validate lines and show preview
            emit SIGshowTransformedSample();
        }
    }
}

void LogfileDialog::showTransformedSample()
{
    qDebug()<<"start:showTransformedSample";
    m_ui->transformedSampleTextEdit->clear();
    
    QString statement;
    bool lastLineHasContent=false;
    QString lastLine="";
    QString line;
    for (int i=0; i<m_sampleLines.count() && i<m_ui->rowsToShow->value();i++)
    {
        line = m_sampleLines.at(i);
        if (lastLineHasContent)
        {
            if (this->m_lineValidator->isValidLogLine(line)) // finish last line and start with this new one
            {
                m_ui->transformedSampleTextEdit->appendPlainText(lastLine); // add this line
                lastLine = line.trimmed(); // start with new line
                lastLineHasContent = true;
            }
            else if (m_lineValidator->isInValidLogLine(line))
            {
                m_ui->transformedSampleTextEdit->appendPlainText(lastLine);
                // just ignore this line.
                lastLine.clear();
                lastLineHasContent = false;
            }
            else // this is continuation of last line
            {
                lastLine.append(line.trimmed());
            }
        }
        else // we have no content, might be after other block than a valid line or when we have first line
        {
            if (m_lineValidator->isValidLogLine(line)) // first real line?
            {
                lastLine = line.trimmed();
                lastLineHasContent=true;
            }
        }
    }
    // add the very last line we read if we have a valid line already
    if (lastLineHasContent)
    {
        m_ui->transformedSampleTextEdit->appendPlainText(lastLine);
    }
    qDebug()<<"LogfileDialog::showTransformedSample: finished";
}

    /*qint64 worked=0;
    int newpercent,lastpercent=0;

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return 2;
    QTextStream in(&file);
    qreal durationtime;
    QString statement;

    bool lastLineHasContent=false;
    QString lastLine="";
    QString line;
    while (!in.atEnd())
    {
        line = in.readLine();
        worked += line.size();

        if (lastLineHasContent)
        {
            if (isStartOfLogLine(line)) // finish last line and start with new one
            {
                if (splitline(lastLine,durationtime,statement))
                {
                    if (!m_loggdata->addStatement(statement,durationtime))
                        qDebug()<<"Problem adding the command "<<statement;
                }
                lastLine = line.trimmed();
                lastLineHasContent = true;
            }
            else if (isInvalidLine(line))
            {
                lastLineHasContent = false;
                if (splitline(lastLine,durationtime,statement))
                {
                    if (!m_loggdata->addStatement(statement,durationtime))
                        qDebug()<<"Problem adding the command "<<statement;
                }
                lastLine.clear();
            }
            else
            {
                lastLine.append(line.trimmed());
            }
        }
        else // we have no content, might be after other block than LOG or when we have first line
        {
            if (isStartOfLogLine(line)) // first real line?
            {
                lastLine = line.trimmed();
                lastLineHasContent=true;
            }
        }

        newpercent=(int)(100*worked/totalsize);
        if (newpercent!=lastpercent)
        {
            qDebug()<<newpercent<<"% done  "<<m_loggdata->getShortStatistics();
            lastpercent=newpercent;
        }
    }
    // add the very last line we read
    if (lastLineHasContent)
    {
        if (splitline(lastLine,durationtime,statement))
        {
            if (!m_loggdata->addStatement(statement,durationtime))
                qDebug()<<"Problem adding the command "<<statement;
        }
        lastLine.clear();
        lastLineHasContent=false;
    }
    qDebug()<<100<<"% done";
    return 0;
}
*/


void LogfileDialog::showLineValidatorData()
{
    if (this->m_lineValidator != NULL)
    {
        m_ui->statementSyntaxEdit->setText(this->m_lineValidator->getStatementStringSyntax());
        m_ui->durationSyntaxEdit->setText(this->m_lineValidator->getDurationStringSyntax());
        m_ui->lineSyntaxEdit->setText(this->m_lineValidator->getValidStringSyntax());
        m_ui->lineSyntaxEditInvalid->setText(this->m_lineValidator->getInvalidStringSyntax());
    }
}

void LogfileDialog::setLineValidation(LineValidator* linevalidator)
{
    this->m_lineValidator = linevalidator;
}
void LogfileDialog::setLineValidation(QString linevalidationString)
{
    this->m_lineValidator = new LineValidator();
    this->m_lineValidator->setValidLinePattern(linevalidationString);
}

LogfileDialog::~LogfileDialog()
{
    this->m_file->close();
    delete m_ui;
}

void LogfileDialog::showSample()
{
    int maxLines = m_ui->rowsToShow->value();
    m_ui->sampleTextEdit->clear();
    for (int i=0;i<maxLines;i++)
        m_ui->sampleTextEdit->appendPlainText(m_sampleLines.at(i));
    emit SIGshowTransformedSample();
    qDebug()<<"LogfileDialog::showSample: pre rehighlight";
    if (this->m_invalidHighlighter == NULL)
    {
        this->m_invalidHighlighter= new InvalidHighlighter(this->m_lineValidator->getInvalidStringSyntax(),this->m_lineValidator->getValidStringSyntax(),m_ui->sampleTextEdit->document());
        //this->m_invalidHighlighter->setPattern(this->m_lineValidator->getInvalidStringSyntax());
    }
    else
    {
        delete this->m_invalidHighlighter;
        this->m_invalidHighlighter= new InvalidHighlighter(this->m_lineValidator->getInvalidStringSyntax(),this->m_lineValidator->getValidStringSyntax(),m_ui->sampleTextEdit->document());
        //this->m_invalidHighlighter->setPattern();
    }
    //this->m_invalidHighlighter->rehighlight();
    qDebug()<<"LogfileDialog::showSample: done rehighlight";
}

void LogfileDialog::changeEvent(QEvent *e)
{
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void LogfileDialog::updateLineSyntax(QString str)
{
    this->m_lineValidator->setValidLinePattern(str);
    emit SIGshowSample();
}
void LogfileDialog::updateInvalidLineSyntax(QString str)
{
    this->m_lineValidator->setInValidLinePattern(str);
    emit SIGshowSample();
}
void LogfileDialog::updateDurationSyntax(QString str)
{
    this->m_lineValidator->setDurationExtractionPattern(str);
    emit SIGshowSample();
}
void LogfileDialog::updateStatementSyntax(QString str)
{
    this->m_lineValidator->setStatementExtractionPattern(str);
    emit SIGshowSample();
}
